
#include "stdafx.h"
#include "inputhandler.h"

using namespace Blox;


InputHandler::InputHandler()
{
	Clear();
}

InputHandler::~InputHandler()
{
	Clear();
}

bool InputHandler::Init()
{
	Clear();

	return true;
}

void InputHandler::Clear()
{
	Action blank;
	for( u32 i=0; i<MAX_ACTIONS; i++ )
		m_aAction[i]=blank;

	memset( m_aKeyStatePrev, STATE_UP, sizeof(u8)*KEY_COUNT );
	memset( m_aKeyState, STATE_UP, sizeof(u8)*KEY_COUNT );
	memset( m_aKeyAction, ACTION_NONE, sizeof(u8)*KEY_COUNT );
	m_uModifiersHeld = 0;
}

void InputHandler::Process()
{
	ForceUpdateKey();

	UpdateModifierKeys();

	DispatchMessages();
}

void InputHandler::KeyMessage( u8 uKey, u8 uState )
{
	u8 uOldState = m_aKeyState[uKey];
	m_aKeyState[uKey] = uState;
	if( uOldState == STATE_UP )
	{
		if( uState == STATE_DOWN )
		{
			m_aKeyAction[uKey] |= ACTION_PRESSED;
		}
	}
	else if( uOldState == STATE_DOWN )
	{
		if( uState == STATE_DOWN )
		{
			m_aKeyAction[uKey] |= ACTION_HELD;
		}
		else if( uState == STATE_UP )
		{
			m_aKeyAction[uKey] |= ACTION_RELEASED;
		}
	}

	if( uState == STATE_DOWN )
	{
		m_aKeyAction[uKey] |= ACTION_DOWN;
	}
}

void InputHandler::ForceUpdateKey()
{
	static int uCurrentKey = 0;

	short sResult = GetKeyState( uCurrentKey );
	
	KeyMessage( uCurrentKey, (sResult&0x80) ? STATE_DOWN : STATE_UP );

	uCurrentKey++;
	uCurrentKey%=KEY_COUNT;
}

void InputHandler::DispatchMessages()
{
	for( u32 i=0; i<MAX_ACTIONS; i++ )
	{
		if( m_aAction[i].fnAction )
		{
			if( (m_aKeyAction[m_aAction[i].uKey] & m_aAction[i].uActions)>0 && ( m_uModifiersHeld == m_aAction[i].uModifierKeys ) )
			{
				m_aAction[i].fnAction( m_aAction[i].pData1 );
			}
		}
	}

	memset( m_aKeyAction, ACTION_NONE, sizeof(u8)*KEY_COUNT );

	//for( u32 i=0; i<KEY_COUNT; i++ )
	//{
	//	if( m_aKeyAction[i] & (u8)ACTION_PRESSED )
	//	{
	//		
	//	}
	//	if( m_aKeyAction[i] & (u8)ACTION_HELD )
	//	{

	//	}
	//	if( m_aKeyAction[i] & (u8)ACTION_RELEASED )
	//	{

	//	}
	//	if( m_aKeyAction[i] & (u8)ACTION_DOWN )
	//	{

	//	}
	//}

	memcpy( m_aKeyStatePrev, m_aKeyState, sizeof(u8)*KEY_COUNT );
}

u32 InputHandler::RegisterAction( Action const & rAction )
{
	u32 uActionID = MAX_ACTIONS;
	for( u32 i=0; i<MAX_ACTIONS; i++ )
	{
		if( m_aAction[i].fnAction == NULL )
		{
			if( uActionID == MAX_ACTIONS )
			{
				uActionID = i;
			}
		}
		//else
		//{
		//	if( m_aAction[i].fnAction == rAction.fnAction )
		//	{
		//		uActionID = i;
		//		break;
		//	}
		//}
	}

	if( uActionID >= MAX_ACTIONS )
	{
		// ERROR
		return UINT_MAX;
	}

	m_aAction[uActionID] = rAction;

	return uActionID;
}

void InputHandler::UpdateModifierKeys()
{
	m_uModifiersHeld = 0;
	if( m_aKeyState[VK_CONTROL]==STATE_DOWN || m_aKeyState[VK_LCONTROL]==STATE_DOWN || m_aKeyState[VK_RCONTROL]==STATE_DOWN )
		m_uModifiersHeld |= KEYMOD_CTRL;
	if( m_aKeyState[VK_SHIFT]==STATE_DOWN || m_aKeyState[VK_LSHIFT]==STATE_DOWN || m_aKeyState[VK_RSHIFT]==STATE_DOWN )
		m_uModifiersHeld |= KEYMOD_SHIFT;
	if( m_aKeyState[VK_MENU]==STATE_DOWN || m_aKeyState[VK_LMENU]==STATE_DOWN || m_aKeyState[VK_RMENU]==STATE_DOWN )
		m_uModifiersHeld |= KEYMOD_ALT;
}

